﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Xml;
using Microsoft.Win32;

using EncodingConvertor.Source;

namespace EncodingConvertor
{
    public partial class frmMain : Form
    {
        string initPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        
        //需要转换的所有文件扩展名
        System.Collections.ArrayList ExtNameList;

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            try
            {
                Config.LoadConfig();
                this.Text += "Beta" + Config.Version.Substring(Config.Version.LastIndexOf(".")+1,5);

                if (Config.SHOWAD.Equals("0"))
                {
                    this.splitContainer1.Panel1Collapsed = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void tsbOpenFolder_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.SelectedPath = initPath;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                initPath = folderBrowserDialog1.SelectedPath;

                if (!Config.FILEFILTER.Trim().Equals(""))
                {
                    string[] strArray = Config.FILEFILTER.Trim().Split(new char[] { '|' });
                    if (strArray.Length % 2 > 0)    //不是2的倍数
                    {
                        MessageBox.Show("文件过滤字符串设置有误!");
                        return;
                    }
                    else
                    {
                        ExtNameList = new System.Collections.ArrayList();
                        string extNm = "";
                        for (int i = 0; i < strArray.Length / 2; i++)
                        {
                            extNm = strArray[i * 2 + 1].Substring(strArray[i * 2 + 1].LastIndexOf("."), strArray[i * 2 + 1].Length - strArray[i * 2 + 1].LastIndexOf("."));
                            ExtNameList.Add(extNm.ToLower());
                        }
                    }
                }
                FindAllFiles(folderBrowserDialog1.SelectedPath);
                ClearControls();
            }
        }

        private void tsbAddFiles_Click(object sender, EventArgs e)
        {
            using (System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog())
            {
                fd.Multiselect = true;
                fd.InitialDirectory = initPath;
                if (!Config.FILEFILTER.Trim().Equals(""))
                    fd.Filter = Config.FILEFILTER.Trim();
                if (DialogResult.OK == fd.ShowDialog())
                {
                    string[] files = fd.FileNames;
                    foreach (string s in files)
                    {
                        this.listSelectedFiles.Items.Add(s);
                    }
                    ClearControls();
                }
            }
        }

        private void tsbDelete_Click(object sender, EventArgs e)
        {
            if (this.listSelectedFiles.SelectedIndex > -1)
            {
                listSelectedFiles.Items.RemoveAt(this.listSelectedFiles.SelectedIndex);
            }
        }

        private void tsbClear_Click(object sender, EventArgs e)
        {
            this.listSelectedFiles.Items.Clear();
            ClearControls();
        }

        private void tsbPase_Click(object sender, EventArgs e)
        {
            string textData = Clipboard.GetText();
            string[] Files = textData.Split(new char[] { '\n' });
            string s = "";
            for (int i = 0; i < Files.Length; i++)
            {
                s = Files[i];
                if (s.IndexOf("\r") > -1)
                    s = s.Replace("\r", "");
                if (!s.Trim().Equals(""))
                    listSelectedFiles.Items.Add(s);
            }
        }

        private void tsbHomePage_Click(object sender, EventArgs e)
        {
            GoURL("http://www.sooot.cn");
        }

        private void tsbOption_Click(object sender, EventArgs e)
        {
            this.ShowOptionForm();
        }

        private void tsbShowAD_Click(object sender, EventArgs e)
        {
            this.splitContainer1.Panel1Collapsed = !this.splitContainer1.Panel1Collapsed;
        }

        private void tsbExecute_Click(object sender, EventArgs e)
        {
            this.txtResult.Text = "文件总数：" + listSelectedFiles.Items.Count.ToString() + "\r\n 正在执行......";
            this.tsslStatus.Text = "执行中...";
            this.toolStripProgressBar1.Maximum = listSelectedFiles.Items.Count;

            //真正执行转换
            int i = 0;
            try
            {
                this.Cursor = System.Windows.Forms.Cursors.WaitCursor;

                for (i = 0; i < listSelectedFiles.Items.Count; i++)
                {
                    ConvertFileEncode(listSelectedFiles.Items[i].ToString());
                    this.toolStripProgressBar1.Value = i;
                }
                this.txtResult.Text += "\r\n完成：" + listSelectedFiles.Items.Count.ToString();
                this.tsslStatus.Text = listSelectedFiles.Items.Count.ToString() + "个文件已完成";
            }
            catch (Exception ex)
            {
                string PathFile = this.listSelectedFiles.Items[i].ToString();
                this.listSelectedFiles.SelectedIndex = i;
                CheckError(PathFile);
                this.txtResult.Text += "\r\n执行文件：" + PathFile + "转换时出现错误：" + ex.Message + "\r\n可能由于文件编码不能识别或者文件内容为空，建议将其移除手动更改格式！\r\n已经完成：" + i.ToString();
                this.tsslStatus.Text = "转换出错";
            }
            finally
            {
                this.Cursor = System.Windows.Forms.Cursors.Default;
            }
        }
        private void tsmiAbout_Click(object sender, EventArgs e)
        {
            Form frm = new frmAbout();
            frm.ShowDialog();
        }

        private void tsmiOption_Click(object sender, EventArgs e)
        {
            this.ShowOptionForm();
        }

        private void ShowOptionForm()
        {
            Form frm = new frmConfig();
            if (frm.ShowDialog() == DialogResult.OK)
            {
            }
        }

        //根据下拉框的值返回相应的编码。
        private Encoding GetSelectEncoding(int i)
        {
            Encoding encode;
            switch (i)
            {
                case 0:
                    encode = System.Text.Encoding.UTF8;
                    break;
                case 1:
                    encode = System.Text.Encoding.UTF7;
                    break;
                case 2:
                    encode = System.Text.Encoding.Unicode;
                    break;
                case 3:
                    encode = System.Text.Encoding.ASCII;
                    break;
                case 4:
                    encode = System.Text.Encoding.GetEncoding(936); //GB2321
                    break;
                case 5:
                    encode = System.Text.Encoding.GetEncoding("BIG5");
                    break;
                default:
                    encode = System.Text.Encoding.UTF8;
                    break;
            }
            return encode;
        }

        /// <summary>
        /// 找到目录下的所有文件，包括子目录
        /// </summary>
        /// <param name="dirs">目录路径</param>        
        /// <returns></returns>
        private void FindAllFiles(string path)
        {
            string[] files = System.IO.Directory.GetFiles(path);
            string extNm = "";
            int pos = 0;
            bool hasAllChar = false;
            foreach (string s in ExtNameList)
            {
                if (s.Equals(".*"))
                    hasAllChar = true;
            }
            foreach (string s in files)
            {
                pos = s.LastIndexOf(".");
                if (pos > -1)
                    extNm = s.Substring(pos, s.Length - pos);
                else
                    extNm = "";
                if (ExtNameList == null || ExtNameList.IndexOf(extNm.ToLower()) > -1 || hasAllChar)
                    listSelectedFiles.Items.Add(s);
            }
            string[] dirs = Directory.GetDirectories(path);
            foreach (string s in dirs)
            {
                FindAllFiles(s);
            }
        }

        private void ConvertFileEncode(string PathFile)
        {
            if (PathFile.Trim().Equals(""))
            {
                return;
            }

            string backupPath = PathFile.Substring(initPath.Length, PathFile.Length - initPath.Length);
            Encoding oriEncode;
            #region 编码识别
            if (Config.SOURCEENCODING == -1)
            {
                IdentifyEncoding ie = new IdentifyEncoding();
                FileInfo fi = new FileInfo(PathFile);
                string encodingName = string.Empty;

                encodingName = ie.GetEncodingName(fi);
                fi = null;

                if (encodingName.ToLower() == "other")
                {
                    txtResult.Text += string.Format("\r\n{0}文件格式不正确或已损坏。 ", PathFile);
                    return;
                }
                else
                {
                    oriEncode = Encoding.GetEncoding(encodingName);
                }
            }
            else
            {
                oriEncode = GetSelectEncoding(Config.SOURCEENCODING);
            }
            #endregion
            string text = File.ReadAllText(PathFile, oriEncode);

            if (!Config.BACKUPPATH.Equals(""))//备份
            {
                string tmpPath = Config.BACKUPPATH;
                tmpPath += backupPath;
                string directory = tmpPath.Substring(0, tmpPath.LastIndexOf("\\"));
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                File.WriteAllText(tmpPath + ".bak", text, oriEncode);
            }

            File.WriteAllText(PathFile, text, GetSelectEncoding(Config.TARGETENCODING));
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.tsslTime.Text = DateTime.Now.ToString();
        }

        private void ClearControls()
        {
            this.toolStripProgressBar1.Value = 0;
            this.txtResult.Text = string.Empty;
            this.tsslStatus.Text = this.listSelectedFiles.Items.Count.ToString() + "个文件准备完毕";
        }

        private void GoURL(string url)
        {
            Process myProcess = new Process();
            string myUrl = url;

            myProcess.StartInfo.FileName = "iexplore.exe";
            myProcess.StartInfo.Arguments = myUrl;
            myProcess.Start();

        }

        private void CheckAndUpdate()
        {
            XmlReader xmlreader;
            string serverVersion = Config.Version;
            string thisVersion = Config.Version;
            string serverURL = "http://www.sooot.cn";

            try
            {
                xmlreader = new XmlTextReader("http://www.sooot.cn/stTools/stFileEncodingConvertor/VerSion.xml");
                while (xmlreader.Read())
                {
                    if (xmlreader.Name == "Version")
                    {
                        serverVersion = xmlreader.GetAttribute("Num");
                    }
                    else if (xmlreader.Name == "URLAddres")
                    {
                        serverURL = xmlreader.GetAttribute("URL");
                    }

                }

                if (serverVersion.CompareTo(thisVersion) > 0)
                {
                    if (MessageBox.Show("有更新版本，是否更新！", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                    {
                        MessageBox.Show(serverURL);
                    }
                }
                else
                {
                    MessageBox.Show("已经是最新版！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void CheckError(string PathFile)
        {
            FileAttributes fa = File.GetAttributes(PathFile);
            if ((fa & FileAttributes.ReadOnly) == (FileAttributes.ReadOnly))//如果是只读属性的话 
            {
                MessageBox.Show(PathFile + "\n该文件为只读文件，无法修改！", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                sbyte[] rawtext;
                rawtext = new sbyte[(int)IdentifyEncoding.FileLength(new FileInfo(PathFile))];
                if (rawtext.Length == 0)
                {
                    MessageBox.Show(PathFile + "\n是空文件，请将其移除再试！", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void FeedBack()
        {
            GoURL("http://www.sooot.cn");
        }

        private void tsmiUpdate_Click(object sender, EventArgs e)
        {
            CheckAndUpdate();
        }

        private void tssmiFeedBack_Click(object sender, EventArgs e)
        {
            FeedBack();
        }
    }
}